<?php
/**
 * Класс предназначен для работы с сессиями
 *
 */
class User_Session {
  private $ascii_session_id;          //Сгенерированный PHP идентификатор сеанса (32 символа)
  private $ID_user_session;       //Идентификатор сеанса, используемый в базе данных (нужен для связи сущностей в базе данных)
  private $logged_in;               //[bool] Логическая переменная, определяющая активность сеанса
  private $ID_user;                 //Идентификатор (берется из БД) текущего зарегистрированного пользователя
  private $sessionTimeout = 8640000;   //Время ожидания. Если период между запросами превышает эту величину, сеанс прерывается.
  private $sessionLifespan = 60480000; //Максимальный срок действия сеанса

  /**
   * Конструктор. Переопределяет ф-ции для работы с сессией
   *
   */
  private function __construct() {
    session_set_save_handler(
      array(&$this, '_session_open_method'),
      array(&$this, '_session_close_method'),
      array(&$this, '_session_read_method'),
      array(&$this, '_session_write_method'),
      array(&$this, '_session_destroy_method'),
      array(&$this, '_session_gc_method')
    );
    //Проверка cookie: переданы ли эти данные и корректны ли они
    $struser_agent = (isset($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : '';

    if (isset($_COOKIE["PHPSESSID"]) && $_COOKIE["PHPSESSID"]) {
      // Проверка сроков давности для безопасности
      $this->ascii_session_id = $_COOKIE["PHPSESSID"];//Идентификатор сеанса

      $arResult = $this->_baseGetCorrectSessionsWithAscii();
      if (sizeof($arResult) == 0) { // Если в базе нет такого идентификатора сесии или срок действия сеанса истек или используется другой пользовательский агент или ( с последнего обращения к странице прошло больше времени, чем время ожидания или не было обращений к странице)
        $failed = 1; // Установка флага failed
        // Удаление из базы данных - периодическая сборка мусора
        // Удаляем сессию с соответствующим ascii_session_id и сессии, у которых истек максимальный срок действия сеанаса
        $this->_baseDeleteIncorrectSessionsAndAsciiSess();
        // Очищаем переменные сеанса
        // Удаляем все переменные сесии, для которых не осталось соответствующей сессии
        $this->_baseDeleteIncorrectSessionsVariables();
        unset($_COOKIE["PHPSESSID"]); // Удаление идентификатора в cookie
      }
    }
    session_set_cookie_params($this->sessionLifespan); // Установка времени жизни данных cookie
    session_start();//Вызовется сначала _session_open,  потом _session_read
  }

  /**
   * Функция обеспечивает работу шаблона Singleton
   * Благодаря ей у нас всегда будет только один объект пользовательской сессии
   *
   * @return object - объект сессии
   */
  static public function instance(){
    static $objSession;
    if (!isset($objSession)) {
      $objSession = new User_Session();
    }
    return $objSession;
  }

  /**
   * Позволяет определить факт нового обращения к странице
   * Должен вызываться на любой странице в которой используется класс сеанса,
   * сразу же после его инстанцирования
   *
   */
  public function impress() {
    if ($this->ID_user_session) {//Если имеется идентификатор сеанса, используемый в базе, то
        if ($this->isLoggedIn()) {
                $lastImpression = $this->_baseGetLastImpression();

                if (time() - strtotime($lastImpression) > 900) {
                User_User::setLoginTime();
                        User_User::addVisit();
                User_User::setStatus(2, $this->getUserId());
        }
      }
        $this->_baseUpdatelast_impression();//Обновляем время последнего обращения
        if ($this->ID_user)
        	User_User::upadteLastImpression($this->ID_user);

      User_User::addHit();
    }
  }

  /**
   * Проверка регистрации пользователя в рамках сеанса
   *
   * @return bool - залогинен или нет
   */
  public function isLoggedIn() {
    return($this->logged_in);
  }

  /**
   * Получение идентификатора пользователя
   *
   * @return int - ID пользователя
   */
  public function getUserId() {
    if ($this->logged_in) {//Если сеанс активен
      return($this->ID_user);
    }
    else {
      return false;
    };
  }

  /**
   * Возвращает 32-символьный идентификатор сеанса PHP
   *
   * @return string - 32-символьный идентификатор сеанса PHP
   */
  public function getSessionIdentifier() {
    return($this->ascii_session_id);
  }

  /**
   * Функция входа
   * Получает логин и пароль
   * Возвращает true, если удалось залогиниться
   *
   * @param string $strUsername - Имя пользователя
   * @param string $strPlainPassword - Пароль
   * @param boolean $Save - Запомнить меня
   * @param boolean $Save - Запомнить меня
   * @return $NO_PASS_LOGIN - ВНИМАНИЕ! вход без пароля только для служебных нужд. БУДЬТЕ ВНИМАТЕЛЬНЫ!
   */
  public function logIn($strUsername, $strmd5Pass, $save,  $NO_PASS_LOGIN = false) {
        if ($NO_PASS_LOGIN) {
          if (Authorization::isEMailExist($strUsername))
            $ID_user = User_User::getUserIdByEMail($strUsername);
          elseif (Authorization::isLoginExist($strUsername))
            $ID_user = User_User::getUserIdByLogin($strUsername);
          else
            throw new Exception('Неправильный логин или пароль, исправьте введенные данные <br />');
        }
        else
      $ID_user = Authorization::logIn($strUsername, $strmd5Pass);

    if ($ID_user) {//Если есть совпадения (логин+пароль)
      $this->ID_user = $ID_user;//Запоминаем id пользователя
      $this->logged_in = true;//Активируем сеанс
      //Обновляем БД
      //Устанавливаем статус активного сеанса, запоминаем id пользователя для текущ0его сеанса
      $this->_baseLogInSession();
      User_User::setLoginTime();
      User_User::addVisit();
      User_User::setStatus(2, $this->getUserId());
      if ($save){
                                $superStr = md5($strUsername . 'superSlovo' . $strmd5Pass . 'superSlovo');
                                setcookie("SaveMe" , $superStr , time() + 60480000, '/');
                                setcookie("ID" , $ID_user , time() + 60480000, '/');
                        }
      return true;
    }
    else { // Если НЕТ совпадений (логин+пароль)
                        throw new Exception('Неправильный логин или пароль, исправьте введенные данные <br />');
    };
  }

  /**
   * Функция автозахода если пользователь ставил галочку "Запомнить меня"
   *
   * @return bool - Запомнили или нет
   */
  public function ifSaveMe() {
        if ($this->logged_in == false) { //Если сеанс не активен
                if (isset($_COOKIE['SaveMe']) && isset($_COOKIE['ID'])) { //Если в куках храняться значения ИД и хэш SaveMe
                        $objDB = Service_Database::instance();
                        //Делаем выборку майла и пароля по ИД
                        $strUserAndPass = 'SELECT `e_mail`, `login`, `pass` FROM `user` WHERE ID_user="' . $_COOKIE['ID'] . '"';
                        $arUserAndPass = $objDB->select($strUserAndPass);
                        if ($arUserAndPass) { //Если есть совпадение
                                $mail = $arUserAndPass[0]['e_mail'];
                                $md5pass = $arUserAndPass[0]['pass'];
                                $login = $arUserAndPass[0]['login'];
                                $superStrMail = md5($mail . 'superSlovo' . $md5pass . 'superSlovo'); //Формируем супер строку =)
                                $superStrLogin = md5($login . 'superSlovo' . $md5pass . 'superSlovo'); //Формируем супер строку =)
                                if ($superStrMail == $_COOKIE['SaveMe'] or $superStrLogin == $_COOKIE['SaveMe']) { //Если супер строка равна хэшу в куках
                                        //Заново логинимся, все довольны =)
                                        $ID_user = Authorization::logIn($login, $md5pass);
                                        if ($ID_user) {//Если есть совпадения (логин+пароль)
                                                $this->ID_user = $ID_user;//Запоминаем id пользователя
                                                $this->logged_in = true;//Активируем сеанс
                                                //Обновляем БД
                                                //Устанавливаем статус активного сеанса, запоминаем id пользователя для текущ0его сеанса
                                                $this->_baseLogInSession();
                                                User_User::setLoginTime();
                                                User_User::addVisit();
                                                User_User::setStatus(2, $this->getUserId());
                                                return true;
                                        }
                                        else { // Если НЕТ совпадений (логин+пароль)
                                                return false;
                                        }
                                }
                        }
                }
        }
  }


  /**
   * Функция выхода
   * Возвращает true, если вышли. false, если сеанс не был активен
   *
   * @return bool - Вышли или нет
   */
  public function logOut() {
    if ($this->logged_in) {//Если сеанс активен
      //Устанавливаем для текущей сессии состоянии НЕ активный сеанс и обнуляем пользователя.
      User_User::setStatus(0, $this->getUserId());
      $this->_baseLogOutSession();
      $this->logged_in = false; //Деактивируем сеанс
      $this->ID_user = 0; //Обнуляем id пользователя
      setcookie("SaveMe"); // Обнуляем значените куки SaveMe
      return true;
    }
    else { // Если сеанс НЕ активен
      return false;
    }
  }

  /**
   * Метод сохраняет сообщение об успешно проведенной операции
   *
   */
  public function saveSuccessMessage($message) {
    $this->__set('success', $message);
  }
  /**
   * Метод сохраняет сообщение о неуспешно проведенной операции
   *
   */
  public function saveErrorMessage($message) {
    $this->__set('error', $message);
  }
  /**
   * Метод удаляет сообщения о проведении опрераций
   *
   */
  public function deleteUserMessages() {
    $objDB = Service_Database::instance();
    $stmt = "DELETE FROM `" . TABLE_SESSION_VARIABLE . "` WHERE `ID_user_session` = " . $this->ID_user_session . " AND ((`variable_name` = 'error') OR (`variable_name` = 'success'))";
    $objDB->query($stmt);
  }
  /**
   * Метод gполчает сообщения о проведении опрераций
   *
   */
  public function getUserMessage() {
    $objDB = Service_Database::instance();
    $stmt = "SELECT `" . TABLE_SESSION_VARIABLE . "`.`variable_name`, `" . TABLE_SESSION_VARIABLE . "`.`variable_value` FROM `" . TABLE_SESSION_VARIABLE . "` WHERE `ID_user_session` = " . $this->ID_user_session . " AND ((`variable_name` = 'error') OR (`variable_name` = 'success'))";
    $arrReturn = $objDB->selectOne($stmt);
    if(!$arrReturn)
      return NULL;
    $arrReturn['variable_value'] = unserialize($arrReturn['variable_value']);
    return $arrReturn;
  }

/**
   * Метод переправляет пользователя на другую страницу. При необходимости сохраняет сообщение в переменную сессиии
   *
   * @param string $location
   * @param string $message
   * @param integer $messageType
   */
  public function moveTo($location, $message = NULL, $messageType = -1) {
    if ($message)
      if ($messageType > 0)
        $this->saveSuccessMessage($message);
      else
        $this->saveErrorMessage($message);
//    Pressure::saveDuration(getCurrentUrl(), 2, Pressure::calculateCurrentDuration());
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $location);
    exit();
  }


/**
 * Эта функция запускается при открытии сессии - сделана на будущее для дополнительных возможных проверок и пр.
 * Получает путь $save_path, по которому должны храниться переменные сеанса и имя файла cookie
 *
 * @param atring $save_path
 * @param string $session_name
 * @return bool
 */
  private function _session_open_method($save_path, $session_name) {
    //Ничего не делаем
    return true;
  }

  /**
   * Эта функция запускается при закрытии сессии - сделана на будущее
   *
   * @return bool
   */
  public function _session_close_method() {
    //Ничего не делаем
    return true;
  }

  /**
   * Эта функция используется при попытке извлечения переменной из массива $_SESSION
   * Ей передается идентификатор сеанса
   * По умолчанию возвращает сериализованное представление массива $_SESSION, но не в нашем случае, т.к. у нас собственная обработка
   *
   * @param integer $id - ID сеанса
   * @return string - Пустая строка
   */
  private function _session_read_method($id) {
    //Используется для проверки существования сеанса
    $struser_agent = (isset($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : '';
    $this->ascii_session_id = $id; //Записываем id сессии
    $failed = 1; //Установка флага failed
    //Проверить наличие данных в базе данных
    //(Есть ли соответствующая текущему id сессия?)
    $arResult = $this->_baseGetSessionById($id);
    if (sizeof($arResult) > 0) { //Если сессия с текущим id существует, то...
      $this->ID_user_session = $arResult[0]["ID_user_session"]; //Запоминаем id сессии из БД
      if ($arResult[0]["logged_in"]==1) { //Если сеанс активен
        $this->logged_in = true; //Активируем сеанс
        $this->ID_user = $arResult[0]["ID_user"]; //Записываем id пользователя
      }
      else { //Если сеанс НЕ активен
        $this->logged_in = false; //Деактивируем сеанс
      }
    }
    else { //Если сессия с текущим id НЕ существует, то...
      $this->logged_in = false; //Деактивируем сеанс
      //Необходимо создать запись в БД
      //Сессия с текущим id, деактивированная, без соответствия пользователя...

      $this->ID_user_session = $this->_baseCreateNewEmptySessionByAscii($id, $struser_agent);
    }
    return(""); // Возвращаем пустую строку
  }

/**
 * Эта функция вызывается при попытке модифицировать массив $_SESSION
 * Ей передается идентификатор сеанса + сериализованное представление массива $_SESSION
 * Возвращает true, если все ок.
 * Вызывается даже если переменные сеанса не зарегистрированы, и при первом вызове записывает сгенерированный идентификатор сеанса
 *
 * @param integer $id - ID сеанса
 * @param string $sess_data - Сериализованное представление массива $_SESSION
 * @return bool
 */
  public function _session_write_method($id, $sess_data) {
    return true;
  }

  /**
   * Вызывается при вызове в коде функции session_destroy();
   *
   * @param integer $id - ID сеанса
   */
  private function _session_destroy_method($id) {
    $objDB = Service_Database::instance();
    $objDB->delete(TABLE_USER_SESSION, array('ascii_session_id' => $id));
  }

  /**
   * Функция сборки мусора.
   * Получает максимальное время жизни данных cookie для текущего сеанса
   * Удаляет любые данные, срок жизни которых превышает заданный
   *
   * @param integer $maxlifetime - Время жизни сеанса
   * @return bool
   */
  private function _session_gc_method($maxlifetime) {
    return true;
  }

  /**
   * Функция работает с БД
   * Функция выбирает из БД все сессии с соответствующим ASCII сессии
   *
   * @return array - Массив с сессией
   */
  private function _baseGetCorrectSessionsWithAscii(){
    $objDB = Service_Database::instance();
    $stmt = "SELECT ID_user_session, logged_in FROM " . TABLE_USER_SESSION . " WHERE ascii_session_id = '" . $this->ascii_session_id . "' AND ((now() - created) < ' " . $this->sessionLifespan . " seconds') AND user_agent='" . $_SERVER['HTTP_USER_AGENT'] . "' AND ((now() - last_impression) <= '".$this->sessionTimeout." seconds' OR last_impression IS NULL)";
    return $objDB->select($stmt);
  }

  /**
   * Функция работает с БД
   * Функция выбирает из БД сессию с соответствующим 32-симв идентификатором
   *
   * @param integer $id - ID сеанса
   * @return array - Массив с сессией
   */
  private function _baseGetSessionById($id){
    $objDB = Service_Database::instance();
    $stmt = "SELECT ID_user_session, logged_in, ID_user FROM " . TABLE_USER_SESSION . " WHERE ascii_session_id = '$id'";
    return $objDB->select($stmt);
  }

  /**
   * Функция работает с БД
   * Удаляет все сессии, у которых истекло время жизни и текущую сессию согласно ее 32симв. идентификатору
   *
   * @return bool - Удалено или нет
   */
  private function _baseDeleteIncorrectSessionsAndAsciiSess(){
    $objDB = Service_Database::instance();
    //$sql = "DELETE FROM " . TABLE_USER_SESSION . " WHERE (ascii_session_id = '". $this->ascii_session_id . "') OR ((now() - created) > $this->sessionLifespan)";
    $sql = "DELETE FROM " . TABLE_USER_SESSION . " WHERE (ascii_session_id = '". $this->ascii_session_id . "')";
    return $objDB->query($sql);
  }


  /**
   * Функция работает с БД
   * Удаляет все переменные сессий, которые ссылаются на уже удаленные сессии
   *
   */
  private function _baseDeleteIncorrectSessionsVariables(){
    $objDB = Service_Database::instance();
    $sql = "DELETE FROM `" . TABLE_SESSION_VARIABLE . "` WHERE ID_user_session NOT IN (SELECT ID_user_session FROM " . TABLE_USER_SESSION . ")";
    $objDB->query($sql);
  }

  /**
   * Функция работает с БД
   * Обновляет время последней активности сессии
   *
   */
  private function _baseUpdatelast_impression(){
    $objDB = Service_Database::instance();
    $sql = "UPDATE " . TABLE_USER_SESSION . " SET last_impression = now() WHERE ID_user_session = " . $this->ID_user_session;
    $objDB->query($sql);
  }

  /**
   * Функция работает с БД
   * Проверяет, есть ли пользователь с соответствующими login+password
   *
   * @param string $strUsername - Имя пользователя
   * @param string $strMD5Password - Пароль в MD5
   * @return array - Массив с пользователем
   */
  private function _baseIsLogInCorrect($strUsername, $strMD5Password){
    $objDB = Service_Database::instance();
    $stmt = "SELECT ID_user FROM " . TABLE_USER . " WHERE nick = '$strUsername' AND md5Pw = '$strMD5Password'";
    return $objDB->select($stmt);
  }

  /**
   * Функция работает с БД
   * Устанавливает необходимые поля у сессии в состояние "Не аутентифицировано"
   *
   */
  function _baseLogOutSession(){
    $objDB = Service_Database::instance();
    //$objDB->query('UPDATE `session` SET `session`.`logged_in` = "false", `session`.`ID_user` = NULL WHERE `session`.`ID_user_session` = "' . $this->ID_user_session . '"');
    //$objDB->query(TABLE_USER_SESSION, array('logged_in' => false, 'ID_user' => 'NULL'), array('ID_user_session' => $this->ID_user_session));
    $objDB->update(TABLE_USER_SESSION, array('logged_in' => false), array('ID_user_session' => $this->ID_user_session));
  }

  /**
   * Функция работает с БД
   * Устанавливает необходимые поля у сессии в состояние "Аутентифицировано"
   *
   */
  function _baseLogInSession(){
    $objDB = Service_Database::instance();
    $objDB->update(TABLE_USER_SESSION, array('logged_in' => true), array('ID_user_session' => $this->ID_user_session));
  }

  /**
   * Функция работает с БД
   * Устанавливает необходимые поля у сессии в состояние "Аутентифицировано"
   *
   * @param string $idAscii - 32-символьный идентификатор сеанса
   * @param string $struser_agent - Агент пользователя
   * @return integer - ID сеанса
   */
  private function _baseCreateNewEmptySessionByAscii($idAscii, $struser_agent){
    $objDB = Service_Database::instance();
    $objDB->query("INSERT INTO `" . TABLE_USER_SESSION . "` (ascii_session_id, logged_in, ID_user, created, user_agent) VALUES ('$idAscii','f', NULL, now(),'$struser_agent')");
    //Получение истинного идентификатора от только что вставленных данных
    $arResult = $objDB->select("SELECT ID_user_session FROM " . TABLE_USER_SESSION . " WHERE ascii_session_id = '$idAscii'");
    return $arResult[0]["ID_user_session"];
  }

  /**
   * Запись значения переменной $nm, относящееся к текущей сессии
   *
   * @param string $nm - Имя параметра
   * @param string $val - Значение параметра
   */
  public function __set($nm, $val) {
    $objDB = Service_Database::instance();
    $strSer = serialize($val);//Сериализуем значение
    $stmt = "SELECT `ID_user_session` FROM `" .TABLE_SESSION_VARIABLE . "` WHERE `ID_user_session` = '" . $this->ID_user_session . "' AND `variable_name` = '" . $nm . "'";
    if ($objDB->isRecordExist($stmt)) {
      $stmt = "UPDATE `" .TABLE_SESSION_VARIABLE . "` SET `variable_value` = '" . $strSer . "' WHERE `ID_user_session` = '" . $this->ID_user_session . "' AND `variable_name` = '" . $nm . "'";
    }
    else{
      //Вставляем значение в БД для текущей сессии, данного названия переменной $nm
      $stmt = "INSERT INTO `" .TABLE_SESSION_VARIABLE . "` (`ID_user_session`,`variable_name`,`variable_value`) VALUES (" . $this->ID_user_session . ",'" . $nm . "','" . $strSer . "')";
    }
    //echo $stmt;
    $objDB->query($stmt);
  }

  /**
   * Удаление значения параметра из сессии
   *
   * @param string $nm - Имя параметра
   */
  public function __delete($nm){
    $objDB = Service_Database::instance();
    $stmt = "DELETE FROM `" . TABLE_SESSION_VARIABLE . "` WHERE ID_user_session = " . $this->ID_user_session . " AND variable_name='" . $nm . "'";
    $objDB->query($stmt);
  }

  /**
   * Функция берет переменую из сессии по имени
   *
   * @param string $nm - Имя параметра
   * @return string - Значение параметра
   */
  public function __get($nm) {
    $objDB = Service_Database::instance();
    //Получаем значение переменной $nm, относящееся к текущей сессии
    $arResult = $objDB->select("SELECT variable_value FROM " . TABLE_SESSION_VARIABLE . " WHERE ID_user_session = " . $this->ID_user_session . " AND variable_name = '" . $nm . "'");
    if (sizeof($arResult)>0) { // Если  есть элементы
      return(unserialize($arResult[sizeof($arResult)-1]["variable_value"]));//возвращаем значение
    }
    else { // Если нет элементов
      return false;
    }
  }

  /**
     * Функция записи массива значений массива переменных, относящихся к текущей сессии
     *
     * @param array $name - массив переменных
     */
    public function __setArray($name) {
        $objDB = Service_Database::instance();
        foreach ($name as $key => $value) {
                $this->__set($key, $value);
/*                      $strSer = serialize($value); # Сериализуем значение
                $stmt = "INSERT INTO `" .TABLE_SESSION_VARIABLE . "` (`ID_user_session`,`variable_name`,`variable_value`) VALUES (" . $this->ID_user_session . ",'" . $key . "','" . $strSer . "')";
                $objDB->query($stmt);*/

        }
     }

         /**
          * Получение массва значений переменных
          *
          * @return false/массив значений переменных
          */
     public function __getArray() {
      $objDB = Service_Database::instance();
      $arr = $objDB->select("SELECT variable_value, variable_name FROM " . TABLE_SESSION_VARIABLE . " WHERE ID_user_session = " . $this->ID_user_session);
      $arResult = array();
      for($i = 0; $i < sizeof($arr); $i++){
      $arResult[$arr[$i]['variable_name']] = $arr[$i]['variable_value'];

      if (sizeof($arResult[$arr[$i]['variable_name']])>0) # Если  есть элементы
        $arResult[$arr[$i]['variable_name']] = unserialize($arr[$i]["variable_value"]); # возвращаем значение # [sizeof($arResult)]
      }
      if (sizeof($arResult)>0)
        return $arResult;
      else # Если нет элементов
        return(false);
        }

        /**
         * Функция удаления записей значений массива переменных
         *
         */
        public function __deleteStr() {
                $objDB = Service_Database::instance();
                $func_list = func_get_args();
                for($i = 0; $i < sizeof($func_list); $i++)
                {
                        $stmt = 'DELETE FROM `' .TABLE_SESSION_VARIABLE . '`
                WHERE `variable_name` = "' . $func_list[$i] . '"';
                        $objDB->query($stmt);
                }
        }
/**
  * Уничтожает лишние сессии
  *
  */
        public static function deleteBadSessions() {
                self::_deleteBadVariables();
                $objDB = Service_Database::instance();
                $stmt = "DELETE FROM `session`
                                WHERE `session`.`last_impression` < DATE_SUB(now(), INTERVAL 15 MINUTE) OR `session`.`last_impression` IS NULL";
                $objDB->query($stmt);
        }
        /**
         * Удаляет ишние переменные сессий
         *
         */
        public static function _deleteBadVariables() {
                $objDB = Service_Database::instance();
                $stmt = "SELECT `ID_session_variable` FROM `session_variable`
                                                LEFT JOIN `session` ON `session`.`ID_user_session` = `session_variable`.`ID_user_session`
                                WHERE `session`.`last_impression` < DATE_SUB(now(), INTERVAL 14 MINUTE) OR `session`.`last_impression` IS NULL";
                $arrIds = $objDB->selectSimpleArray($stmt);
                if(!$arrIds)
                  return false;
                $stmt = "DELETE FROM `session_variable`
                                WHERE `ID_session_variable` IN(" . implode(',', $arrIds) . ")";
                $objDB->query($stmt);
                return true;
        }
  /**
   * Функция работает с БД
   * Обновляет время последней активности сессии
   * @return mixed - Массив с пользователем
   */
  private function _baseGetLastImpression() {
    $objDB = Service_Database::instance();
    $sql = "SELECT `last_impression` FROM " . TABLE_USER_SESSION . " WHERE `ID_user_session` = '" . $this->ID_user_session . "'";
    return $objDB->selectSimpleField($sql);
  }


  public function loginByOpenId($openId) {
    $objDB = Service_Database::instance();//Получаем подключение к БД
    $stmt = "SELECT `ID_user`, `login`, `pass` FROM " . TABLE_USER . " WHERE `open_id` = '" . $openId . "'";  //формируем SQL-запрос
    $arrUser = $objDB->select($stmt);
    if (sizeof($arrUser) > 0) {
        $objSession = User_Session::instance();
                        $ID_user = Authorization::logIn($arrUser[0]['login'], $arrUser[0]['pass']);
                        if ($ID_user) {//Если есть совпадения (логин+пароль)
                                $this->ID_user = $ID_user;//Запоминаем id пользователя
                                $this->logged_in = true;//Активируем сеанс
                                //Обновляем БД
                                //Устанавливаем статус активного сеанса, запоминаем id пользователя для текущ0его сеанса
                                $this->_baseLogInSession();
                                User_User::setLoginTime();
                                User_User::addVisit();
                                User_User::setStatus(2, $this->getUserId());
                                $this->moveTo(W_ABSPATH);
                        }
                        else { // Если НЕТ совпадений (логин+пароль)
                                return false;
                        }
    }
	}
	
	/**
	 * Метод получает количество обращений пользователем за последние секунды
	 *
	 * @param int $seconds
	 * @return int
	 */
	public static function getTreatmentsAmountByIp($seconds) {
		$ip = $_SERVER['REMOTE_ADDR'];
    $objDB = Service_Database::instance();
    $stmt = "SELECT COUNT(`ip`) FROM `ip_check`
             WHERE `ip` = '" . $ip . "' AND `created` > DATE_SUB(now(), INTERVAL " . intval($seconds) . " SECOND);";
    return $objDB->selectSimpleField($stmt);
	}
	
	/**
	 * Метод вставляет информацию о новом обращении
	 *
	 */
	public static function insertNewTreatment() {
    $ip = $_SERVER['REMOTE_ADDR'];
		$objDB = Service_Database::instance();
    $stmt = "INSERT INTO `ip_check` (`ip`, `created`) VALUES ('" . $ip . "', now());";
    $objDB->selectSimpleField($stmt);
	}
	
	/**
	 * Метод очищает таблицу обращений к серверу
	 *
	 * @param int $seconds
	 * @return int
	 */
	public static function clearTreatments($seconds) {
    $objDB = Service_Database::instance();
    $stmt = "DELETE FROM `ip_check`
             WHERE `created` < DATE_SUB(now(), INTERVAL " . intval($seconds) . " SECOND);";
    return $objDB->selectSimpleField($stmt);
	}
}
?>